package com.dirox.confluence.labelmanagement.action;

import com.atlassian.confluence.core.Beanable;
import com.atlassian.confluence.core.ConfluenceActionSupport;
import com.atlassian.confluence.core.service.ValidationError;
import com.atlassian.confluence.labels.LabelManager;
import com.atlassian.confluence.spaces.SpaceManager;
import com.atlassian.confluence.util.ajax.AjaxResponse;
import com.dirox.confluence.labelmanagement.service.LabelManagementService;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * MergeLabelAjaxAction extends ConfluenceActionSupport implements Beanable
 * <p>
 * This class implement merge label action.
 * 
 */
public class MergeLabelAjaxAction extends ConfluenceActionSupport implements
		Beanable {

	private static final long serialVersionUID = 1L;
	private static Logger log = Logger.getLogger(MergeLabelAjaxAction.class);
	private SpaceManager spaceManager;
	private LabelManagementService labelManagementService;
	private Object bean;
	private String secondLabel;
	private String firstLabel;
	private String spaceKey;
	private LabelManager labelManager;

	/**
	 * This method executes the merge label action
	 * @return the result of action in String (ERROR|SUCCESS)
	 * @throws Exception
	 */
	public String mergeLabel() throws Exception {
		// Validate input values
		if (!validateInput()) {
			return ERROR;
		}

		try {
			// Check if spaceKey is not blank then merge in this space,
			// else merge in all spaces.
			if (StringUtils.isNotBlank(spaceKey)) {
				labelManagementService.mergeLabelInSpace(spaceKey, firstLabel,
						secondLabel);
			} else {
				labelManagementService.mergeLabelInAllSpaces(firstLabel,
						secondLabel);
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e.getCause());
			bean = AjaxResponse.failure(getText(e.getMessage()));
			return ERROR;
		}

		bean = AjaxResponse.success(getText("label-management.code.success"));
		return SUCCESS;
	}

	/**
	 * Method for validating input for merge label action.
	 * <p>
	 * - First, validate if labels are empty, return false.<br/>
	 * - Second, validate if two labels are the same, return false.<br/>
	 * - Third, validate if labels do not exist, return false.<br/>
	 * - Final, validate if space does not exist (when space is specified)
	 * @return boolean
	 */
	private boolean validateInput() {
		// check if the labels are empty
		if (StringUtils.isBlank(firstLabel) || StringUtils.isBlank(secondLabel)) {
			bean = AjaxResponse
					.failure(getText("label-management.error.empty.label"));
			return false;
		}
		// check if the new label contains "space" character
				if (secondLabel.contains(" ")) {
					bean = AjaxResponse
							.failure(getText("label-management.error.space.character"));
					return false;
		}
		// check if the labels are the same
		if (secondLabel.equalsIgnoreCase(firstLabel)) {
			bean = AjaxResponse
					.failure(getText("label-management.merge.error.duplicate.label"));
			return false;
		}
		// validate label
		ValidationError error = labelManagementService
				.getLabelValidationError(secondLabel);
		if (error != null) {
			bean = AjaxResponse.failure(getText("label-management.error.invalid.character"));
			return false;
		}
		// check if the labels do not exist
		if (labelManager.getLabel(firstLabel) == null
				|| labelManager.getLabel(secondLabel) == null) {
			bean = AjaxResponse
					.failure(getText("label-management.error.not.exist.label"));
			return false;
		}
		// check if the space does not exist
		if (StringUtils.isNotBlank(spaceKey)
				&& spaceManager.getSpace(spaceKey) == null) {
			bean = AjaxResponse
					.failure(getText("label-management.error.not.exist.space"));
			return false;
		}
		return true;
	}

	@Override
	public Object getBean() {
		return bean;
	}

	public String getSecondLabel() {
		return secondLabel;
	}

	public void setSecondLabel(String secondLabel) {
		this.secondLabel = secondLabel;
	}

	public String getFirstLabel() {
		return firstLabel;
	}

	public void setFirstLabel(String firstLabel) {
		this.firstLabel = firstLabel;
	}

	public String getSpaceKey() {
		return spaceKey;
	}

	public void setSpaceKey(String spaceKey) {
		this.spaceKey = spaceKey;
	}

	public void setSpaceManager(SpaceManager spaceManager) {
		this.spaceManager = checkNotNull(spaceManager);
	}

	public void setLabelManagementService(
			LabelManagementService labelManagementService) {
		this.labelManagementService = checkNotNull(labelManagementService);
	}

	public void setLabelManager(LabelManager labelManager) {
		this.labelManager = checkNotNull(labelManager);
	}
}
